#include "supersnake.h"
#include <math.h>

supersnake::supersnake(void)
{
	length = 0;
}

supersnake::supersnake(int posx,int posy,world* w)
{
	length = 1;
	direction = 'd';
	sc = 0;
	changespeed = false;

	if(w->map[posx][posy]->gettype()==blank)
	{
		w->map[posx][posy]->settype(badhead);
		sks.push_back(w->map[posx][posy]);
	}
	//snake_head->setnote(posx,posy,head);
}


bool supersnake::move(world* w)
{
	if(sks.size() == 0)
	{
		return false;
	}

	int x = sks.front()->getx();
	int y = sks.front()->gety();
	int nextx;
	int nexty;

	int fx;
	int fy;

	note* flag;
	float distance;

	std::list<note*> tmp;

	for(int i = 0; i < 4; i ++)
	{
		switch (i)
		{
		case 0:
			if(w->map[x][y+1]->gettype() == blank || w->map[x][y+1]->gettype() == foods || w->map[x][y+1]->gettype() == traps)
			{
				tmp.push_back(w->map[x][y+1]);
			}
			break;
		case 1:
			if(w->map[x+1][y]->gettype() == blank || w->map[x+1][y]->gettype() == foods || w->map[x+1][y]->gettype() == traps)
			{
				tmp.push_back(w->map[x+1][y]);
			}
			break;
		case 2:
			if(w->map[x][y-1]->gettype() == blank || w->map[x][y-1]->gettype() == foods || w->map[x][y-1]->gettype() == traps)
			{
				tmp.push_back(w->map[x][y-1]);
			}
			break;
		case 3:
			if(w->map[x-1][y]->gettype() == blank  || w->map[x-1][y]->gettype() == foods || w->map[x-1][y]->gettype() == traps)
			{
				tmp.push_back(w->map[x-1][y]);
			}
			break;
		default:
			break;
		}
	}

	if(tmp.size() == 0)
	{
		return false;
	}

	flag = tmp.front();
	fx = w->getfood()->getx();
	fy = w->getfood()->gety();

	distance = pow((flag->getx() - fx),2) + pow((flag->gety() - fy),2);

	std::list<note*>::iterator it;
	for(it = tmp.begin();it!= tmp.end();it++)
	{
		if( pow(((*it)->getx() - fx),2) + pow(((*it)->gety() - fy),2) < distance)
		{
			distance = pow(((*it)->getx() - fx),2) + pow(((*it)->gety() - fy),2);
			flag = *it;
		}
	}

	nextx = flag->getx();
	nexty = flag->gety();

	if(w->map[nextx][nexty]->gettype()==blank)
	{
		changespeed = false;
		w->map[nextx][nexty]->settype(badhead);
		
		std::list<note*>::iterator it;
		for(it = sks.begin();it!= sks.end();it++)
		{
			w->map[(*it)->getx()][(*it)->gety()]->settype(badbody);
		}
		sks.push_front(w->map[nextx][nexty]);
		w->map[sks.back()->getx()][sks.back()->gety()]->settype(blank);
		sks.pop_back();
	}
	else if(w->map[nextx][nexty]->gettype()==foods)
	{
		changespeed = true;
		w->map[nextx][nexty]->settype(badhead);
		w->map[x][y]->settype(badbody);
		sks.push_front(w->map[nextx][nexty]);
		w->putfood(w);
	}
	else if(w->map[nextx][nexty]->gettype()==traps)
	{
		changespeed = true;
		w->map[nextx][nexty]->settype(blank);

		std::list<note*>::iterator it;
		for(it = sks.begin();it!= sks.end();it++)
		{
			if(it != sks.begin())
			{
				w->map[(*it)->getx()][(*it)->gety()]->settype(badbody);
			}
		}
		w->map[sks.back()->getx()][sks.back()->gety()]->settype(blank);
		sks.pop_back();
		w->puttrap(w);
		if(sks.size() == 0)
		{
			return false;
		}
	}
	else
	{
		return false;
	}

	if(nextx == x)
	{
		if(nexty > y)
		{
			direction = 'w';
		}
		else if(nexty < y)
		{
			direction = 's';
		}
	}
	else if(nexty == y)
	{
		if(nextx > x)
		{
			direction = 'd';
		}
		else if(nextx < x)
		{
			direction = 'a';
		}
	}

	if(direction == 'd')
	{
		sks.front()->getSprite()->setRotation(0);
	}
	else if(direction == 's')
	{
		sks.front()->getSprite()->setRotation(90);
	}
	else if(direction == 'a')
	{
		sks.front()->getSprite()->setRotation(180);
	}
	else if(direction == 'w')
	{
		sks.front()->getSprite()->setRotation(-90);
	}

	return true;
}

void supersnake::setdr(char d)
{
	direction = d;
}

char supersnake::getdr()
{
	return direction;
}

int supersnake::getsc()
{
	return sc;
}

int supersnake::getlength()
{
	return sks.size();
}
bool supersnake::changeSpeed()
{
	return changespeed;
}
void supersnake::resetchangeSpeed()
{
	changespeed = false;
}

note supersnake::getheadPoint()
{
	return *sks.front();
}

supersnake::~supersnake(void)
{
}
